Development of software applications typically involve the frequent use of debuggers to analyze logical errors and other problems that occur during the execution of the application. Such debugging occurs both while the application is being developed or enhanced, and after the application has been provided (e.g., released) for general use. In order for a debugger application to present a user with accurate information and control of a running computer program, the program must have been compiled with a special debugging option. This option, for example, causes the compiler to generate a set of debugging tables with information that enables the debugger to map the low-level machine instructions of the program to the high-level source code with which the user is familiar. To make this mapping usable, the compiler generally must not re-order, or replace program instructions dictated by the user in the source code. This is in direct conflict with the optimizations that modern compilers can make in order to increase the speed and performance of the program. There are a great number of such optimizations and it is the norm for all of them to be disabled during a compilation using the debugging option.
Therefore, users debugging large computer programs typically have to choose between program execution speed (compiled optimizations) and debugging efficacy (compiled debugger information).
Furthermore, the program generated by compiling with such debugging options may be a significantly different program and may behave differently compared to the original program. Subtle timing windows, memory usage, and even compiler bugs may cause a change in behavior. The program may, in fact, no longer exhibit the symptom that the debugger was called upon to research.